
package com.example.fast_food_orders.service;

import com.example.fast_food_orders.exception.BusinessException;
import com.example.fast_food_orders.model.Item;
import com.example.fast_food_orders.model.ItemType;
import com.example.fast_food_orders.model.Order;
import com.example.fast_food_orders.model.OrderStatus;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.*;

// 订单服务类
@Service
public class OrderService {
    private static final String BURGER_NAME = "汉堡";
    private static final String FRIES_NAME = "薯条";
    private static final double COMBO_PRICE = 25;
    private static final double DISCOUNT_THRESHOLD = 100;
    private static final double DISCOUNT_AMOUNT = 10;
    private static final double VIP_DISCOUNT_RATE = 0.9;

    // 创建订单（核心方法）
    public Order createOrder(List<Item> items, boolean isVIP) {
        // 检查是否包含至少一个主食
        boolean hasMainDish = false;
        for (Item item : items) {
            if (item.getType() == ItemType.MAIN) {
                hasMainDish = true;
                break;
            }
        }
        if (!hasMainDish) {
            System.out.println("订单不包含主食，即将抛出异常");
            try {
                throw new BusinessException("订单必须包含至少一个主食");
            } catch (BusinessException e) {
                // 在这里添加一些输出语句，查看异常是否真的进入了 catch 块
                System.out.println("异常被捕获: " + e.getMessage());
                throw e; // 重新抛出异常，确保它能传递到测试用例中
            }
        }

        validateItems(items);  // 校验商品列表是否合法
        double totalPrice = calculateTotalPrice(items, isVIP);  // 计算订单总价
        String orderId = UUID.randomUUID().toString();  // 生成唯一的订单ID
        // 创建订单对象，包含订单ID、商品列表、订单状态、总价格和创建时间
        Order order = new Order(orderId, items, OrderStatus.CREATED, totalPrice, LocalDateTime.now());
        return order;  // 返回创建的订单
    }

    // 取消订单
    public void cancelOrder(Order order) {
        // 如果订单已经支付，则不能取消
        if (order.getStatus() == OrderStatus.PAID) {
            throw new BusinessException("已支付的订单不可取消");
        }
        // 如果订单创建超过30分钟，则可以取消
        if (order.getCreateTime().plusMinutes(30).isBefore(LocalDateTime.now())) {
            order.setStatus(OrderStatus.CANCELLED);  // 设置订单状态为已取消
        } else {
            // 否则抛出异常，订单未超过30分钟，不能取消
            throw new BusinessException("订单创建未超过30分钟，不可取消");
        }
    }

    // 验证商品列表是否合法
    private void validateItems(List<Item> items) {
        // 校验订单商品数量是否超过限制，单笔订单最多5个商品项
        if (items.size() > 5) {
            throw new BusinessException("单笔订单最多包含5个商品项");
        }

        boolean hasMainDish = false;  // 标记是否有主食
        boolean hasDessert = false;   // 标记是否有甜品

        // 遍历商品列表
        for (Item item : items) {
            if (item.getType() == ItemType.MAIN) {
                hasMainDish = true;  // 如果有主食，将主食标记为true
            }
            if (item.getType() == ItemType.DESSERT) {
                hasDessert = true;   // 如果有甜品，将甜品标记为true
            }
            // 校验冰咖啡的售卖时间，如果当前时间是下午3点后，则不允许冰咖啡的购买
            if ("冰咖啡".equals(item.getId()) && LocalDateTime.now().getHour() >= 15) {
                throw new BusinessException("冰咖啡在下午3点后不能售卖");
            }
        }

        // 如果订单没有主食，则抛出异常
        if (!hasMainDish) {
            throw new BusinessException("订单必须包含至少一个主食");
        }

        // 如果有甜品但没有主食，则抛出异常
        if (hasDessert && !hasMainDish) {
            throw new BusinessException("甜品不能单独购买（必须搭配主食）");
        }
    }

    private double calculateTotalPrice(List<Item> items, boolean isVIP) {
        boolean hasBurger = false;
        boolean hasFries = false;
        // 标记是否使用了套餐
        boolean comboUsed = false;

        /**
         * 遍历订单中的所有商品，检查是否同时存在汉堡和薯条。
         * 如果同时存在，将总价初始化为套餐价格（25 元）。
         * 从订单商品列表中移除一个汉堡和一个薯条，只保留剩余的商品。
         * 标记套餐已使用。
         */

        // 检查是否满足套餐条件（汉堡 + 薯条）
        for (Item item : items) {
            if (BURGER_NAME.equals(item.getName())) {
                hasBurger = true;
            }
            if (FRIES_NAME.equals(item.getName())) {
                hasFries = true;
            }
        }

        double total = 0;
        if (hasBurger && hasFries) {
            // 移除套餐商品
            List<Item> remainingItems = new ArrayList<>();
            boolean burgerRemoved = false;
            boolean friesRemoved = false;
            for (Item item : items) {
                if (BURGER_NAME.equals(item.getName()) && !burgerRemoved) {
                    burgerRemoved = true;
                } else if (FRIES_NAME.equals(item.getName()) && !friesRemoved) {
                    friesRemoved = true;
                } else {
                    remainingItems.add(item);
                }
            }
            total = COMBO_PRICE;
            items = remainingItems;
            comboUsed = true;
        }
        /**
         * 使用 Map 统计每种饮料的数量。
         * 遍历 Map，如果某种饮料的数量大于等于 2，则第二杯及以后的饮料按半价计算。
         * 将饮料的价格累加到总价中。
         *
         */

        // 检查是否有两杯同款饮料
        Map<String, Integer> drinkCount = new HashMap<>();
        for (Item item : items) {
            if (item.getType() == ItemType.DRINK) {
                drinkCount.put(item.getName(), drinkCount.getOrDefault(item.getName(), 0) + 1);
            }
        }
        for (Map.Entry<String, Integer> entry : drinkCount.entrySet()) {
//            遍历 Map，如果某种饮料的数量大于等于 2，则第二杯及以后的饮料按半价计算。
            if (entry.getValue() >= 2) {
                for (Item item : items) {
                    if (item.getType() == ItemType.DRINK && entry.getKey().equals(item.getName())) {
                        if (entry.getValue() > 1) {
                            total += item.getPrice() / 2;
                            entry.setValue(entry.getValue() - 1);
                        } else {
                            total += item.getPrice();
                        }
                    }
                }
            } else {
                for (Item item : items) {
                    if (item.getType() == ItemType.DRINK && entry.getKey().equals(item.getName())) {
                        //                            将饮料的价格累加到总价中。
                        total += item.getPrice();
                    }
                }
            }
        }

        // 计算非饮料和非套餐商品的价格
//        遍历剩余的商品，将非饮料商品的价格累加到总价中。
        for (Item item : items) {
            if (item.getType() != ItemType.DRINK) {
                total += item.getPrice();
            }
        }

        // 总价 > 100 且非周末
        /**
         * 获取当前日期和时间，判断是否为周末。
         * 如果总价超过 100 元且不是周末，则减去 10 元的满减优惠。
         *
         */
        LocalDateTime now = LocalDateTime.now();
        DayOfWeek dayOfWeek = now.getDayOfWeek();
        boolean isWeekend = dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY;
        if (total > DISCOUNT_THRESHOLD && !isWeekend) {
            total -= DISCOUNT_AMOUNT;
        }

        // 是否是 VIP 用户
        if (isVIP) {
            total *= VIP_DISCOUNT_RATE;
        }

        return total;
    }
}